package com.giornoadd.timex.service;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import com.giornoadd.timex.model.Timesheet;
import com.giornoadd.timex.util.DateUtil;
import com.giornoadd.timex.util.HibernateUtil;

/**
 * Manages database operations for Timesheet table.
 * @author anil
 */
public class TimesheetManagerExtras
{
    @SuppressWarnings("unchecked")
	public List<Timesheet> getTimesheets(String statusCode)
    {
        List<Timesheet> timesheetList = null;

        EntityManager entityManager = HibernateUtil.getEntityManager();
        entityManager.getTransaction();
        timesheetList = entityManager.createQuery(
                "from Timesheet" + " where statusCode = ?").setParameter(0,
                statusCode).getResultList();
        entityManager.getTransaction().commit();

        return timesheetList;
    }
    
    /**
     * Demonstrates use of Hibernate's Session.getNamedQuery method.
     */
    @SuppressWarnings("unchecked")
	public List<Timesheet> getTimesheetsUsingNamedQuery(
            int employeeId,
            Date periodEndingDate)
    {
        List<Timesheet> timesheetList = null;

        EntityManager entityManager = HibernateUtil.getEntityManager();
        entityManager.getTransaction();
        System.err.println("periodEndingDate = " + periodEndingDate);
        timesheetList = entityManager.createNamedQuery(
                "getTimesheetsByEmployeeIdAndPeriodEndingDate").setParameter(
                "employeeId", employeeId).setParameter("periodEndingDate",
                periodEndingDate).getResultList();
        entityManager.getTransaction().commit();

        return timesheetList;
    }

    /** 
     * Demonstrates use of Hibernate's Session.createCriteria method.
     */
    public List<Timesheet> getTimesheetsUsingCriteria(int employeeId)
    {
        List<Timesheet> timesheetList = null;
        EntityManager entityManager = HibernateUtil.getEntityManager();
        entityManager.getTransaction();
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Timesheet> criteria = builder.createQuery( Timesheet.class );
        Root<Timesheet> timesheetRoot = criteria.from( Timesheet.class );
        criteria.select( timesheetRoot );
        criteria.where( builder.equal( timesheetRoot.get("employeeId"), employeeId ) );

        entityManager.getTransaction().commit();

        return timesheetList;
    }

    /** 
     * Saves a list of Timesheets 
     */
    public int saveTimesheetsWithTransaction(List<Timesheet> timesheets)
    {
        if (timesheets == null || timesheets.size() < 1) return 0;

        Timesheet timesheet;
        int saved = 0;
        EntityManager entityManager = HibernateUtil.getEntityManager();
        try
        {
        	entityManager.getTransaction();
            for (int i = 0; i < timesheets.size(); i++)
            {
                timesheet = (Timesheet) timesheets.get(i);
                entityManager.merge(timesheet);
                saved++;
            }

            entityManager.getTransaction().commit();
        } catch (Exception e)
        {
        	entityManager.getTransaction().rollback();
        }

        return saved;
    }

    /**
     * Demonstrates use of Hibernate's Session.createSQLQuery method.
     */
    public int getDaysLeftTillPeriodEnd()
    {
        EntityManager entityManager = HibernateUtil.getEntityManager();
        int daysLeft = -1;
        String sql = "select datediff('dd', NOW, ?) AS daysleft"
                + " from timesheet";
        Integer valueObject = (Integer) entityManager.createQuery(sql).setParameter(0,
                        DateUtil.getCurrentPeriodEndingDate()).getSingleResult();
        if (valueObject != null) daysLeft = valueObject.intValue();
        return daysLeft;
    }
}
